<!-- lss 自定义组件 -->
<template>
	<!-- #ifndef APP-NVUE -->
	<view ref="clear-pop-content">
		<view v-if="showBox"
			 class="shadow-box" 
			 :style="{display:display, transition: transitionModel, opacity: opacity}"  />
	<!-- #endif -->
		 <view ref="clear-pop-app-content" 
				class="content-box"
			   :style="{ top: boxTop + 'px', left: left + 'px', 
						transition: transition,
						width: (winW - left * 2) + 'px'}"
			   @touchstart="touchstart"
			   @touchmove="touchmove"
			   @touchend="touchend">
			<view class="content-title" :style="{height: titleHeight + 'px', width: (winW - left * 2) + 'px',}">
				<slot name="title"></slot>
			</view>
			<!-- #ifndef APP-NVUE -->
			<scroll-view 
				ref="contentBox"
				:scroll-y="scrollY"
				:scroll-top="scrollTop"
				@scroll="scroll"
				style="height: 100%;"
				:style="{paddingTop: titleHeight + 'px'}">
				<slot />
			</scroll-view>
			<!-- #endif -->
			
			<!-- #ifdef APP-NVUE -->
			<scroller offset-accuracy="1"
					show-scrollbar="false"
					:style="{height: (winH - top) + 'px', width: (winW - left * 2) + 'px', paddingTop: titleHeight + 'px'}"
					:scrollable="scrollY" 
					@scroll="scroll">
				<slot/>
			</scroller>
			<!-- #endif -->
		
		<!-- #ifndef APP-NVUE -->
		</view>
		<!-- #endif -->
	</view>
</template>

<script>
	// #ifdef APP-NVUE
	import Binding from 'weex-bindingx';
	const domModule = weex.requireModule('dom')
	// #endif
	
	export default {
		props: {
			top: { // 距离顶部的位置 （px）
				type: Number,
				default: 240
			},
			bottom: {  // 距离顶部的位置（px）
				type: Number,
				default: 500
			},
			left: { // 左右2测的空白距离
				type: Number,
				default: 0
			},
			titleHeight: { // 头的高度
				type: Number,
				default: 0
			},
			opacityMax: {  // 透明度 h5端使用
				type: Number,
				default: .45
			},
			duration: { // 动画时长 h5端使用
				type: Number,
				default: .3
			},
			showBox: { // 是不是需要使用蒙层 h5端使用
				type: Boolean,
				default: false
			},
		},
		
		watch:{
			bottom(val) {
				this.boxTop = this.bottom;
				this.topHeight = this.bottom - this.top 
			},
			
			top(val) {
				this.topHeight = this.bottom - this.top 
			}
		},
		
		data() {
			return {
				scrollY: false, // 是不是可以滚动
				startClientY: 0,
				startClientX: 0,
				lastClientY: 0,
				scrollTop: 0,
				
				winH: 740, // 屏幕高度
				winW: 350, // 屏幕宽度
				boxTop: 500, // 距离顶部高度定位
				// h5 s
				direction: 'toTop', // 向上或者向下
				state: 'unscroll', // 是滚动还是 执行展开/隐藏动画
				transition: '', // 动画
				transitionModel: '',
				display: 'none',
				opacity: 0,
				// h5 end
				topHeight: 200, // APP向上滑动距离
			}
		},
		
		mounted() {
			const _this = this;
			uni.getSystemInfo({
				success: (res) => {
					let height = res.windowHeight;
					let width = res.windowWidth;
					
					// #ifdef H5
				    let clearPop = _this.$refs['clear-pop-content'].$el;
				    clearPop.ontouchmove = function(e){
				        e.preventDefault();
				    }
					// #endif
					
					_this.winH = height
					_this.winW = width
					_this.boxTop = _this.bottom;
					_this.topHeight = _this.bottom - _this.top 
				}	
			})
		},
		methods: {
			scroll(e) {
				// #ifndef APP-NVUE
				this.scrollTop =  e.detail.scrollTop;
				this.state = this.scrollTop == 0 ? "unscroll" : "scroll";
				// #endif
				
				// #ifdef APP-NVUE
				this.scrollTop =  e.contentOffset.y
				// #endif
			},
			touchstart(e) {
				// #ifndef APP-NVUE
				e.preventDefault();
				this.startClientY = e.touches[0].clientY;
				this.lastClientY = this.startClientY;
				this.setDom('start');
				// #endif
				
				// #ifdef APP-NVUE
				this.startClientX = e.changedTouches[0].pageX;
				this.startClientY = e.changedTouches[0].pageY;
				// #endif
			},
			touchmove(e) {
				// #ifndef APP-NVUE
				const clientY = e.touches[0].clientY;
				const touchDistance = clientY - this.startClientY
				
				this.direction = touchDistance > 0 ? "toBottom" : "toTop";
				this.scrollTop = this.scrollTop < 100 && touchDistance > 10 ? 0 : this.scrollTop
				this.state = this.scrollTop == 0 ? "unscroll" : "scroll";
				
				/*两种情况执行方法：
				1. 当前元素不在顶部
				2. 运动方向向下&&contBox元素的滚动值为0&&当前状态不是滚动*/
				if(this.boxTop != this.top || (this.direction == "toBottom" && this.scrollTop == 0 && this.state != "scroll")){
					this.boxTop += clientY - this.lastClientY;
					this.boxTop = this.boxTop > this.bottom ? this.bottom : this.boxTop;
					this.boxTop = this.boxTop < this.top ? this.top : this.boxTop;
					
					this.opacity = this.opacityMax * (this.bottom - this.boxTop)/(this.bottom - this.top);
					this.setDom("move");
				}
				
				this.lastClientY=clientY;
				// #endif
			},
			touchend(e) {
				// #ifndef APP-NVUE
				if(this.state=="scroll")return
				// 触摸大于 10 往下执行
				const touchDistance = this.startClientY - this.lastClientY
				// 触摸不够再弹回去
				if (Math.abs(touchDistance) < 10) {
					this.direction = this.opacity > 0.1 ?  'toTop' : 'toBottom';
					// return
				}
				this.boxTop = this.direction == "toBottom" ?  this.bottom : this.top;
				this.opacity = this.direction=="toBottom" ? 0 : this.opacityMax;
				this.setDom("end");
				// #endif
				
				// #ifdef APP-NVUE
				var endx, endy;
				endx = e.changedTouches[0].pageX;
				endy = e.changedTouches[0].pageY;
				var direction = this.getDirection(this.startClientX, this.startClientY, endx, endy);
				this.caseDirection(direction)
				// #endif
			},
			/*
			* @param direction
			* @des toBottom/ toTop
			*/ 
			btnClick(direction) {
				// #ifndef APP-NVUE
				this.boxTop = direction == 'toBottom' ? this.bottom : this.top;
				this.direction = direction;
				this.setDom("end");
				// #endif
				// #ifdef APP-NVUE
				const num = direction == 'toBottom' ? 2 : 1
				this.caseDirection(num)
				// #endif
			},
			
			// h5 的方法 start --------------
			setDom(state) {
				var _this=this;
				switch (state){
					case "start":
						this.transition="none";
						this.transitionModel="none";
						break;
					case "move":
						break;
					case "end":
						this.transition = "top "+this.duration+"s, height "+this.duration+"s";
						this.display= this.direction == "toBottom" ? "none" : "block";
						this.opacity = this.direction =="toBottom" ? 0 : this.opacityMax;
						this.transitionModel = "opacity "+this.duration+"s";
						this.scrollY = this.direction === "toBottom" ? false : true;
						setTimeout(function(){
							_this.display = _this.direction === "toBottom" ? "none" : "block";
						},300)
						
						this.$emit('callback', this);
						break;
					default:
						break;
				}
			},
			// APP的方法 start ============
			getEl: function(el) {
				if (typeof el === 'string' || typeof el === 'number') return el;
				if (WXEnvironment) {
					return el.ref;
				} else {
					return el instanceof HTMLElement ? el : el.$el;
				}
			},
			
			// 获取角度
			getAngle(angx, angy) {
				return Math.atan2(angy, angx) * 180 / Math.PI;
			},
					
			// 根据起点终点返回方向 1向上 2向下 3向左 4向右 0未滑动
			getDirection(startx, starty, endx, endy) {
				var angx = endx - startx;
				var angy = endy - starty;
				var result = 0;
				//如果滑动距离太短
				if (Math.abs(angx) < 2 && Math.abs(angy) < 2) {
					return result;
				}
				var angle = this.getAngle(angx, angy);
				if (angle >= -135 && angle <= -45) {
					result = 1;
				} else if (angle > 45 && angle < 135) {
					result = 2;
				} else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
					result = 3;
				} else if (angle >= -45 && angle <= 45) {
					result = 4;
				}
				return result;
			},
			// 根据direction执行不同方法
			caseDirection(direction) {
				switch (direction) {
					// 未滑动！
					case 0:
						break;
						// 向上滑动	
					case 1:
						if (this.direction == 'toTop') {
							this.goTop();
							this.direction = 'toBottom'
							this.scrollY = true
						}
						break;
						// 向下滑动	
					case 2:
						if (this.direction == 'toBottom' && this.scrollTop == 0) {
							this.goBottom();
							this.direction = 'toTop'
							this.scrollY = false
						}
						break;
						// 向左
					case 3:
						break;
						// 向右
					case 4:
						break;
					default:
				}
			},
			// 上滑操作
			goTop() {
				let box = this.getEl(this.$refs['clear-pop-app-content']);
				let topHeight = this.topHeight;

				Binding.bind({
					eventType: 'timing',
					exitExpression: {
						origin: 't>800'
					},
					props: [{
						element: box,
						property: 'transform.translateY',
						expression: {
							origin: "easeOutQuint(t, 0, - " + topHeight + ", 800)"
						}
					}]
				});
				const _this = this;
				_this.direction = 'toTop'
				_this.$emit('callback', _this);
			},
					
			// 下滑操作
			goBottom() {
				let box = this.getEl(this.$refs['clear-pop-app-content']);
				let topHeight = this.topHeight
				
				Binding.bind({
					eventType: 'timing',
					exitExpression: {
						origin: 't>800'
					},
					props: [{
						element: box,
						property: 'transform.translateY',
						expression: {
							origin: "easeOutQuint(t, - " + topHeight + ", " + topHeight + ", 800)"
						}
					}, ]
				});
				const _this = this;
				_this.direction = 'toBottom'
				_this.$emit('callback', _this);
			}
		}
	}
</script>

<style >
/* #ifndef APP-NVUE */
.shadow-box{
	width: 100%;
	height: 100%;
	position: fixed;
	top: 0;
	left: 0;
	z-index: 1;
	background-color: black;
	opacity: 0;
	display: none;
}
/* #endif */
.content-box{
	/* #ifndef APP-NVUE */
	width: 100%;
	left: 0;
	bottom: 0;
	right: 0;
	z-index: 2;
	box-sizing: border-box;
	/* #endif */
	position: fixed;
	background-color: #FFFFFF;
	border-top-left-radius: 4px;
	border-top-right-radius: 4px;
	overflow: hidden;
	background-color: #FFFFFF;
	border-top-left-radius: 4px;
	border-top-right-radius: 4px;
	overflow: hidden;
	background-color: #f6f7fb;
	border-radius: 12px 12px 0px 0px;
	border: 1rpx solid #ccccce;
}
.content-title {
	position: absolute;
	width: 100%;
	left: 0;
	top: 0;
}
</style>
